package com.icesoft.core.web.controller;

import cn.hutool.core.map.MapUtil;
import com.icesoft.core.common.helper.Resp;
import com.icesoft.core.web.helper.RequestHold;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定义错误页面和接口响应
 *
 * @ignore
 */
@RestController
@Slf4j
public class ErrorHtmlController extends BasicErrorController {
    private final Map<HttpStatus, String> statusPageMap = new HashMap<>();

    private final String contextPathPre;

    public ErrorHtmlController(ErrorAttributes errorAttributes, ServerProperties serverProperties) {
        super(errorAttributes, new ErrorProperties());
        statusPageMap.put(HttpStatus.NOT_FOUND, "404.html");
        statusPageMap.put(HttpStatus.FORBIDDEN, "403.html");
        statusPageMap.put(HttpStatus.INTERNAL_SERVER_ERROR, "500.html");
        String contextPath = serverProperties.getServlet().getContextPath();
        if ("/".equals(contextPath)) {
            contextPathPre = contextPath;
        } else {
            contextPathPre = contextPath + "/";
        }
    }

    @Override
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        HttpStatus status = this.getStatus(request);
        String page = contextPathPre + "error/" +
                statusPageMap.getOrDefault(status, "error.html") +
                "#!" + request.getAttribute("javax.servlet.error.request_uri");
        Map<String, String> params = RequestHold.getRequestParamMap(request);
        if (!params.isEmpty()) {
            page = page + "?" + MapUtil.join(params, "&", "=");
        }

        return new ModelAndView(new RedirectView(page));
    }

    @Override
    public ResponseEntity error(HttpServletRequest request) {
        Map<String, Object> body = this.getErrorAttributes(request, this.getErrorAttributeOptions(request, MediaType.ALL));
        HttpStatus status = this.getStatus(request);
        String msg = String.valueOf(body.get("message"));
        if (StringUtils.isBlank(msg)) {
            msg = status.toString();
        }
        return new ResponseEntity(Resp.error(status.value()).msg(msg).toString(), getStatus(request));
    }
}
